package com.zlf.mvc.config;

import com.zlf.constant.CrowdConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author ：张利锋
 * @date ：Created in 2020/11/21 20:26
 * @description： TOOD
 * @version: 1.0
 */
//表示这是一个配置类
@Configuration
@EnableWebSecurity
// 启用全局方法权限控制功能，并且设置 prePostEnabled = true。
// 保证@PreAuthority、 @PostAuthority、@PreFilter、@PostFilter 生效
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class CrowdfundingSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    UserDetailsService userDetailsService;
    @Autowired
    BCryptPasswordEncoder passwordEncoder;
    @Override
    protected void configure(AuthenticationManagerBuilder builder) throws Exception {
        //内存版
        //auth.inMemoryAuthentication().withUser("tom").password("123").roles("admin");
        //正式数据库版
        builder.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder);
    }

    @Override
    protected void configure(HttpSecurity security) throws Exception {
        security.authorizeRequests().
                antMatchers("/admin/to/login/page")  //要放行的资源
                .permitAll()                    //允许所有人访问
                .antMatchers("/index.jsp","/bootstrap/**","/css/**","/fonts/**","/img/**","/jquery/**"," /layer/**","/script/**","/ztree/**","/crowd/**")
                .permitAll()
//                .antMatchers("/admin/page") // 针对分页显示 Admin 数据设定访问控制
//                .hasRole("经理")                  // 要求具备经理角色
                .anyRequest()               //其他任何请求
                .authenticated()            //已认证才能访问
                .and()
                .exceptionHandling()
                .accessDeniedHandler(new AccessDeniedHandler(){
                    //内部类设置跳转的页面信息
                    @Override
                    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
                        httpServletRequest.setAttribute("exception",new Exception(CrowdConstant.MESSAGE_ACCESS_DENIED));
                        httpServletRequest.getRequestDispatcher("/WEB-INF/system-error.jsp").forward(httpServletRequest,httpServletResponse);
                    }
                })
                .and()
                .formLogin()                //开启表单验证
                .loginPage("/admin/to/login/page")      //指定登录页面
                .loginProcessingUrl("/security/do/login")       //表单请求
                .defaultSuccessUrl("/admin/to/main/page")       //登录成功后页面
                .usernameParameter("loginAcct")         //验证参数
                .passwordParameter("userPswd")
                .and()
                .csrf()                 //关闭跨站请求防御
                .disable()
                .logout()               //开启退出
                .logoutUrl("/security/do/logout")          //退出登录
                .logoutSuccessUrl("/admin/to/login/page");  //退出后页面

        super.configure(security);
    }
}
